package mbsl.main;

import java.util.prefs.Preferences;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

import mbsl.main.MainFrame.StatusPanel;
import mbsl.system.Core;
import mbsl.system.TextProvider;
import mbsl.ui.ImageLoader;
import mbsl.util.SWTUtils;

/** This is the class controlling the main frame */
public class MainController {
	public MainController(Core pCore) {
		mCore = pCore;
		mDisplay = pCore.getDisplay();
		mFrame = new MainFrame(mDisplay);
		tp = Core.tp;

		mStatusPanel = mFrame.getStatusPanel();
		
		MenuItem item = getMenuBarController().add(
					tp.get("ui.menu.file") + 
					"//" + 
					tp.get("ui.menu.file.exit"), SWT.PUSH);
		
		item.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				closeWindow();
			}
		});
		item.setImage(ImageLoader.getImage(mDisplay, "exit"));
		
		mFrame.getShell().addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent pE) {
				closeWindow();
			}
		});
	}
	/** Returns a menu bar controller */
	public MenuBarController getMenuBarController() {
		if (mMenuBarController == null)
			mMenuBarController = new SimpleMenuBarController();
		
		return mMenuBarController;
	}
	/** Returns a status bar controller */
	public StatusBarController getStatusBarController() {
		return new SimpleStatusBarController();
	}
	/** Returns the Shell this class controls */
	public Shell getWindow() {
		return mFrame.getShell();
	}
	/** Returns true if the passed TabItem currently has focus, and false otherwise */
	public boolean hasFocus(TabItem pItem) {
		return mFrame.getTabFolder().getSelection()[0] == pItem;
	}
	/** Returns the tab folder of the main frame */
	public TabFolder getTabFolder() {
		return mFrame.getTabFolder();
	}
	/** Returns the Core instance which serves this class */
	public Core getCore() {
		return mCore;
	}
	/**
	 * Starts the main UI.
	 * <p>
	 * This is the method where the application 'rests' while waiting for UI input.
	 */
	public void start() {
		mFrame.getShell().setBounds(
				prefs.getInt("x", 0), 
				prefs.getInt("y", 0), 
				prefs.getInt("width", 1000), 
				prefs.getInt("height", 750)
		);
		mFrame.getShell().setMaximized(prefs.getBoolean("maximised", false));
		
		mFrame.open();
		
		mCore.closeLoadingScreen();
		
		SWTUtils.block(mFrame.getShell());
	}
	/**
	 * Sends the close command to the frame
	 */
	private void closeWindow() {
		Rectangle bounds = mFrame.getShell().getBounds();
		
		prefs.putBoolean("maximised", mFrame.getShell().getMaximized());
		prefs.putInt("x", bounds.x);
		prefs.putInt("y", bounds.y);
		prefs.putInt("width", bounds.width);
		prefs.putInt("height", bounds.height);
		
		mFrame.close();
	}
	/**
	 * A full implementation of the StatusBarController, which controls the status bar at the bottom of the main frame.
	 */
	private class SimpleStatusBarController extends StatusBarController {
		@Override
		public void release() {
			if (mStatusPanelOwner == this) {
				if (mParent != null) {
					mStatusPanelOwner = mParent;
					
					mParent = null;
				} else
					mStatusPanelOwner = null;
			}
		}

		@Override
		public boolean requestOwnership(boolean pForce) {
			if (pForce || mStatusPanelOwner == null) {
				mStatusPanelOwner = this;
				
				return true;
			} else
				return false;
		}
		@Override
		public boolean requestOwnership(StatusBarController pParent) {
			if (mStatusPanelOwner == pParent) {
				mParent = mStatusPanelOwner;
				
				mStatusPanelOwner = this;
				
				return true;
			} else
				return false;
		}

		@Override
		public void setInfo(String pMessage) {
			if (canWrite())
				mStatusPanel.setInfo(pMessage);
		}

		@Override
		public void setProgress(int pPercentage) {
			if (canWrite())
				mStatusPanel.setProgress(pPercentage);
		}

		@Override
		public void setStatus(Status pStatus) {
			if (canWrite())
				mStatusPanel.setStatus(pStatus.name());
		}
		private boolean canWrite() {
			return mStatusPanelOwner == null || mStatusPanelOwner == this;
		}
		
		private StatusBarController mParent;
	}
	private class SimpleMenuBarController implements MenuBarController {
		@Override
		public MenuItem add(String pPath) {
			return add(pPath, SWT.PUSH);
		}
		@Override
		public MenuItem add(String pPath, int pStyle) {
			return add(pPath, pStyle, -1);
		}
		@Override
		public MenuItem add(String pPath, int pStyle, int pIndex) {
			return mFrame.getMenuItem(pPath, pStyle, pIndex);
		}
		@Override
		public void remove(String pPath) {
			mFrame.removeMenuItem(pPath);
		}
	}
	private TextProvider tp;
	private Core mCore;
	private Display mDisplay;
	private MainFrame mFrame;
	private MenuBarController mMenuBarController;
	private StatusPanel mStatusPanel;
	private StatusBarController mStatusPanelOwner;
	private static Preferences prefs = Core.getPreferences().node("ui");
}